package com.easy.frame.base.api.threadPool;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 用于创建自定义线程池的工具类
 *
 * @author 86131
 */
@Slf4j
public class ThreadPoolUtil {

    private enum Executor {

        I;
        private final ThreadPoolExecutor EXECUTOR = buildThreadPoolExecutor();

        public ThreadPoolExecutor getExecutor() {
            return EXECUTOR;
        }
    }

    /**
     * 直接创建线程池
     */
    public static ThreadPoolExecutor creatThreadPool() {
        threadPoolStatus("创建任务");
        return Executor.I.getExecutor();
    }

    /**
     * 修改线程池的大小
     */
    public static void creatThreadPool(int corePoolSize, int maximumPoolSize, int blockQueue)
            throws InterruptedException {
        if (!StringUtils.isEmpty(corePoolSize)) {
            Executor.I.getExecutor().setCorePoolSize(corePoolSize);
        }
        if (!StringUtils.isEmpty(maximumPoolSize)) {
            Executor.I.getExecutor().setMaximumPoolSize(maximumPoolSize);
        }
        if (!StringUtils.isEmpty(blockQueue)) {
            ResizableCapacityLinkedBlockQueue<?> queue = (ResizableCapacityLinkedBlockQueue<?>) Executor.I.getExecutor().getQueue();
            queue.setCapacity(blockQueue);
        }
        threadPoolStatus("改变之后");
        //Thread.currentThread().join();
    }

    /**
     * 获取线程池的状态数据
     */
    public static void threadPoolStatus(String name) {
        ThreadPoolExecutor executor = Executor.I.getExecutor();
        ResizableCapacityLinkedBlockQueue<?> queue = (ResizableCapacityLinkedBlockQueue<?>) executor.getQueue();
        log.info(Thread.currentThread().getName() + "-" + name + "-:" +
                "核心线程数:" + executor.getCorePoolSize() +
                " 活动线程数:" + executor.getActiveCount() +
                " 最大线程数:" + executor.getMaximumPoolSize() +
                " 线程池活跃度:" + divide(executor.getActiveCount(), executor.getMaximumPoolSize()) +
                " 任务完成数:" + executor.getCompletedTaskCount() +
                " 队列大小:" + (queue.size() + queue.remainingCapacity()) +
                " 当前排队线程数:" + queue.size() +
                " 队列剩余大小:" + queue.remainingCapacity()

        );
    }

    /**
     * 关闭线程池
     */
    public static void shutdown() {
        if (!Executor.I.getExecutor().isShutdown()) {
            Executor.I.getExecutor().shutdown();
        }
    }

    private static ThreadPoolExecutor buildThreadPoolExecutor() {
        return new ThreadPoolExecutor(
                2,
                5,
                60,
                TimeUnit.SECONDS,
                new ResizableCapacityLinkedBlockQueue<>(10),
                new ThreadFactoryBuilder().setNameFormat("ThreadChangeDemo").build());
    }

    private static String divide(int num1, int num2) {
        return String.format("%1.2f%%", Double.parseDouble(num1 + "")
                / Double.parseDouble(num2 + ""));
    }

}
